package ar.edu.caece.pl.asem.model.impl.treeelements;

import ar.edu.caece.pl.asem.model.impl.SymbolTable;
import ar.edu.caece.pl.asem.temp.TemporalGenerator;

public class Invocacion extends AbstractElement {

	public Invocacion() {
		this.label = "CALL";
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Invocacion))
			return false;
		Invocacion other = (Invocacion) obj;
		if (label == null) {
			if (other.label != null)
				return false;
		} else if (!label.equals(other.label))
			return false;
		return true;
	}

	@Override
	public void generateASMCode() {
		StringBuffer sb = new StringBuffer();

		this.place = TemporalGenerator.getInstance().getActualTemporal();

		String functionName = this.getChildren().get(0).getName();
		
		// Pasaje de PARAMETROS al METODO
		// Hay que hacer un intercambio de variables con temporales de por medio
		if (this.getChildren().get(1).getChildren().size() > 0) {
			int i = 0;
			for (AbstractElement parameter : this.getChildren().get(1)
					.getChildren()) {
				
				// Se genera el codigo del parametro, puede ser una variable o una operacion aritmetica o otro llamado a una funcion, entre otras
				// operaciones
				parameter.parent = this;
				parameter.generateASMCode();
				sb.append(parameter.code);
				
				// nombre de la variable que es el parametro de la funcion, se obtiene de la definicion del metodo en la
				// tabla de simbolos
				String parameterName = SymbolTable.getInstance().getAmbiente("main")
						.getParametros().get(i).getName();
				String parameterEnvName = SymbolTable.getInstance().getAmbiente("main")
				.getParametros().get(i).getEnvName();
				
				sb.append("\t mov " + parameterEnvName + "_" + parameterName + ", ax \n");
				
				i++;
				
			}
		}
		TemporalGenerator.getInstance().releaseTemporal();

		// LLamada a la funcion
		sb.append("\t CALL " + functionName + " \n");

		// Devolucion de la funcion
		sb.append("\t mov ax, " + "ret" + "_"
				+ this.getChildren().get(0).getEnvName() + "_" + functionName
				+ " \n");
		sb.append("\t mov " + this.place + ",ax \n");

		this.code = sb.toString();
	}
}
